from crispy_forms.layout import render_to_string
from django.http import HttpResponse
from django.views import View
from django.views.generic.edit import ContextMixin
from django import forms as djforms
from django.utils.translation import gettext_lazy as _

from .lib import (
    HTMXProjectSubCreateFormViewNoPK,
    HTMXProjectSubUpdateFormViewNoPK,
    ProjectSubIndexRedirectView,
    ProjectSubDetailViewNoPK,
    template_path,
)

from .. import forms, models

HGR_FORMSET_CONFIGS = {
    'international': {
        'model': models.HGRInternationalCooperation,
        'formset': forms.HGRInternationalCooperationFormSet,
        'readonly_formset': forms.HGRInternationalCooperationReadOnlyFormSet,
    },
    'collection': {
        'model': models.HGRCollection,
        'formset': forms.HGRCollectionFormSet,
        'readonly_formset': forms.HGRCollectionReadOnlyFormSet,
    },
    'storage': {
        'model': models.HGRStorage,
        'formset': forms.HGRStorageFormSet,
        'readonly_formset': forms.HGRStorageReadOnlyFormSet,
    },
    'material_export': {
        'model': models.HGRMaterialExport,
        'formset': forms.HGRMaterialExportFormSet,
        'readonly_formset': forms.HGRMaterialExportReadOnlyFormSet,
    },
    'data_filing': {
        'model': models.HGRDataFiling,
        'formset': forms.HGRDataFilingFormSet,
        'readonly_formset': forms.HGRDataFilingReadOnlyFormSet,
    }
}


class HGRFormsetMixin(ContextMixin):
    readonly_formset = False

    def get_formset_queryset(self, form_type):
        """Get queryset for a specific formset type"""
        model = HGR_FORMSET_CONFIGS[form_type]['model']
        return (
            model.objects.none() if not self.object else
            model.objects.filter(HGR=self.object)
        )
    
    def get_formset_configs(self):
        """Get configurations for all formsets with their titles"""
        configs = []
        titles = {
            'international': _('国际合作批准'),
            'collection': _('采集批准'),
            'storage': _('保藏批准'),
            'material_export': _('材料出境批准'),
            'data_filing': _('数据备案批准'),
        }
        
        for form_type, config in HGR_FORMSET_CONFIGS.items():
            FormSetClass = config['readonly_formset'] if self.readonly_formset else config['formset']
            
            formset_kwargs = {
                'queryset': self.get_formset_queryset(form_type),
                'prefix': form_type
            }
            
            if self.request.POST:
                formset_kwargs.update({
                    'data': self.request.POST,
                    'files': self.request.FILES,
                })
            
            configs.append({
                'formset': FormSetClass(**formset_kwargs),
                'title': titles[form_type],
                'form_type': form_type
            })
            
        return configs
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        formset_configs = self.get_formset_configs()
        context["formset_configs"] = formset_configs
        return context

    def form_valid(self, form):
        context = self.get_context_data()
        formsets = [formset_config['formset'] for formset_config in context["formset_configs"]]
            
        if all(formset.is_valid() for formset in formsets):
            obj = form.save(commit=False)
            obj.project = self.get_project()
            obj.save()
            form.store_upload_files(obj, self.request.user)
            self.object = obj
            
            for formset in formsets:
                instances = formset.save(commit=False)
                
                # Map forms to their instances
                for form, instance in zip(
                    [f for f in formset.forms if f.has_changed() and not f.cleaned_data.get('DELETE', False)],
                    instances
                ):
                    instance.HGR = self.object
                    instance.save()
                    form.store_upload_files(instance, self.request.user)
                    
                for obj in formset.deleted_objects:
                    obj.delete()
            return super().form_valid(form)
        return self.render_to_response(context)

class HGRHTMXAddFormView(View):
    def get(self, request, *args, **kwargs):
        form_type = kwargs.get("form_type")
        if form_type not in HGR_FORMSET_CONFIGS:
            return HttpResponse(status=400)
            
        config = HGR_FORMSET_CONFIGS[form_type]
        formset = config['formset'](
            queryset=config['model'].objects.none(),
            prefix=form_type
        )
        
        form = formset.empty_form
        form.fields['DELETE'].widget = djforms.HiddenInput()
        
        return HttpResponse(
            render_to_string(
                template_path('human_genetic_resource/partials/form.html'),
                {'prefix': form_type, 'form': form, 'index': '__prefix__'}
            )
        )

        

class HumanGeneticResourceIndexView(ProjectSubIndexRedirectView):
    model = models.HumanGeneticResource
    detail_view_name = "project:human_genetic_resource/detail"
    create_view_name = "project:human_genetic_resource/create"

class HumanGeneticResourceCreateView(
    HGRFormsetMixin,
    HTMXProjectSubCreateFormViewNoPK
):
    create_view_name = "project:human_genetic_resource/create"
    detail_view_name = "project:human_genetic_resource/detail"
    form_class = forms.HumanGeneticResouceForm
    template_name = template_path("human_genetic_resource/index.html")

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["in_create"] = True
        return context

class HumanGeneticResourceDetailView(
    HGRFormsetMixin,
    ProjectSubDetailViewNoPK
):
    model = models.HumanGeneticResource
    form_class = forms.HumanGeneticResouceForm
    template_name = template_path("human_genetic_resource/index.html")
    readonly_formset = True

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["in_view"] = True
        return context


class HumanGeneticResourceUpdateView(
    HGRFormsetMixin,
    HTMXProjectSubUpdateFormViewNoPK,
):
    model = models.HumanGeneticResource
    form_class = forms.HumanGeneticResouceForm
    template_name = template_path("human_genetic_resource/index.html")
    htmx_template_name = template_path("human_genetic_resource/htmx.html")
    update_view_name = "project:human_genetic_resource/update"
    detail_view_name = "project:human_genetic_resource/detail"
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["in_edit"] = True
        return context

